package org.afs.gescol.component.edt.gwt.client.presenter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.afs.gescol.component.edt.gwt.client.factory.EdtComponentClientFactory;
import org.afs.gescol.component.edt.gwt.client.service.EdtServicesGwt;
import org.afs.gescol.component.edt.gwt.client.service.EdtServicesGwtAsync;
import org.afs.gescol.component.edt.gwt.shared.ConstantesKeysModel;
import org.scub.foundation.framework.gwt.module.client.callback.IntegrityControlAsyncCallback;
import org.scub.foundation.framework.gwt.module.client.factory.ClientFactory;
import org.scub.foundation.framework.gwt.module.client.mvp.management.alert.AlertPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.management.confirm.ConfirmPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.management.error.ErrorEvent;
import org.scub.foundation.framework.gwt.module.client.mvp.management.error.ErrorPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.management.loading.LoadingEvent;
import org.scub.foundation.framework.gwt.module.client.mvp.management.loading.LoadingPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.presenter.Presenter;
import org.scub.foundation.framework.gwt.module.client.mvp.view.View;
import org.scub.foundation.framework.gwt.module.client.util.composants.suggestbox.HasSuggestListBoxHandler;
import org.scub.foundation.framework.gwt.module.shared.IdLabelModel;

import com.bradrydzewski.gwt.calendar.client.Appointment;
import com.bradrydzewski.gwt.calendar.client.Calendar;
import com.bradrydzewski.gwt.calendar.client.CalendarViews;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets.ForIsWidget;

/**
 * Presenter for time's table.
 * @autor Kobla GBENYO (kobla.gbenyo@gmail.com)
 */
public class EmploiDuTempsPresenter extends Presenter {

    private EdtServicesGwtAsync edtServicesGwt = EdtServicesGwt.App.getInstance();

    private EmploiDuTempsView view = EdtComponentClientFactory.getEmploiDuTempsView();

    private Date edtCurrentDate;

    private Map<String, IdLabelModel> constantes;

    private ConstantesKeysModel constantesKeys;

    @Override
    public void onShow(final ForIsWidget container) {
        fireEventGlobalBus(new LoadingEvent(true));
        final Long idYear = constantes.get(constantesKeys.getOpenedYearKey()).getId();
        final Long idPeriod = constantes.get(constantesKeys.getOpenedPeriodKey()).getId();
        final Long idDefaultClass = constantes.get(constantesKeys.getDefaultClassKey()).getId();
        edtServicesGwt.getEdtContents(idYear, idPeriod, idDefaultClass, new IntegrityControlAsyncCallback<List<Appointment>>(view) {
            @Override
            public void onFail(Throwable caught) {
                fireEventGlobalBus(new LoadingEvent(false));
                fireEventGlobalBus(new ErrorEvent(caught));
            }
            @Override
            public void onSuccess(List<Appointment> result) {
                fireEventGlobalBus(new LoadingEvent(false));
                view.getClassValue().setValue(constantes.get(constantesKeys.getDefaultClassKey()));
                displayEdt(result);
                container.add(view.asWidget());
            }
        });
    }

    protected void displayEdt(List<Appointment> result) {
        edtCurrentDate = view.getEdt().getDate();
        edtCurrentDate.setDate(view.getEdt().getDate().getDate() - view.getEdt().getDate().getDay() + 1);
        view.getEdt().clearAppointments();
        view.getEdt().setView(CalendarViews.DAY, 7);
        view.getEdt().getSettings().setIntervalsPerHour(4);
        view.getEdt().getSettings().setPixelsPerInterval(15);
        view.getEdt().getSettings().setEnableDragDrop(false);
        view.getEdt().getSettings().setEnableDragDropCreation(false);
        view.getEdt().getSettings().setEnableDragDropCreation(false);
        view.getEdt().getSettings().setWorkingHourStart(6);
        view.getEdt().getSettings().setWorkingHourEnd(17);
        view.getEdt().suspendLayout();
        if (result != null) {
            view.getEdt().addAppointments((ArrayList)result);
        }
        // TODO : view.getEdt().scrollToHour(6);
        view.getEdt().resumeLayout();
        setEdtDate();
    }

    @Override
    public void onDetach() {
        // TODO Auto-generated method stub
    }

    @Override
    public void onBind() {
        view.getPrecedent().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                edtCurrentDate.setDate(edtCurrentDate.getDate() - 7);
                setEdtDate();
            }
        });
        view.getCourant().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                edtCurrentDate = new Date();
                edtCurrentDate.setDate(edtCurrentDate.getDate() - edtCurrentDate.getDay() + 1);
                setEdtDate();
            }
        });
        view.getSuivant().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                edtCurrentDate.setDate(edtCurrentDate.getDate() + 7);
                setEdtDate();
            }
        });
        view.getClassValue().addValueChangeHandler(new ValueChangeHandler<IdLabelModel>() {
            @Override
            public void onValueChange(ValueChangeEvent<IdLabelModel> event) {
                fireEventGlobalBus(new LoadingEvent(true));
                final Long idYear = constantes.get(constantesKeys.getOpenedYearKey()).getId();
                final Long idPeriod = constantes.get(constantesKeys.getOpenedPeriodKey()).getId();
                edtServicesGwt.getEdtContents(idYear, idPeriod, event.getValue().getId(), new IntegrityControlAsyncCallback<List<Appointment>>(view) {
                    @Override
                    public void onFail(Throwable caught) {
                        fireEventGlobalBus(new LoadingEvent(false));
                        fireEventGlobalBus(new ErrorEvent(caught));
                    }
                    @Override
                    public void onSuccess(List<Appointment> result) {
                        fireEventGlobalBus(new LoadingEvent(false));
                        displayEdt(result);
                    }
                });
            }
        });
    }

    private void setEdtDate() {
        view.getEdt().setDate(edtCurrentDate);
    }

    @Override
    public void initView() {
        view.init();
    }

    /**
     * Get class suggest list box handler.
     * @return the handler
     */
    public HasSuggestListBoxHandler<IdLabelModel> getClassSuggestHandler() {
        return view.getClassSuggestHandler();
    }

    /**
     * Get print boutton handler.
     * @return the handler
     */
    public HasClickHandlers getPrintClickHandlers() {
        return view.getPrintClickHandlers();
    }

    /**
     * Set the value of constantes.
     * @param constantes the constantes to set
     */
    public void setConstantes(Map<String, IdLabelModel> constantes) {
        this.constantes = constantes;
    }

    public void initPresenter() {
        final LoadingPresenter loadingPresenter = ClientFactory.getLoadingPresenter();
        final ErrorPresenter errorPresenter = ClientFactory.getErrorPresenter();
        final ConfirmPresenter confirmPresenter = ClientFactory.getConfirmPresenter();
        final AlertPresenter alertPresenter = ClientFactory.getAlertPresenter();

        addChildPresenter(loadingPresenter);
        addChildPresenter(errorPresenter);
        addChildPresenter(confirmPresenter);
        addChildPresenter(alertPresenter);

        errorPresenter.showPresenter(null);
        loadingPresenter.showPresenter(null);
        confirmPresenter.showPresenter(null);
        alertPresenter.showPresenter(null);
    }

    /**
     * Set the value of constantesKeys.
     * @param constantesKeys the constantesKeys to set
     */
    public void setConstantesKeys(ConstantesKeysModel constantesKeys) {
        this.constantesKeys = constantesKeys;
    }

    /**
     * Home view interface.
     */
    public interface EmploiDuTempsView extends View {

        /**
         * Get the edt.
         * @return the edt.
         */
        Calendar getEdt();

        /**
         * Get button click handler.
         * @return the handler.
         */
        HasClickHandlers getPrecedent();

        /**
         * Get button click handler.
         * @return the handler.
         */
        HasClickHandlers getCourant();

        /**
         * Get button click handler.
         * @return the handler.
         */
        HasClickHandlers getSuivant();

        /**
         * Get print button click handler.
         * @return the handler.
         */
        HasClickHandlers getPrintClickHandlers();

        /**
         * Get class suggest handlers.
         * @return the handler.
         */
        HasSuggestListBoxHandler<IdLabelModel> getClassSuggestHandler();

        /**
         * Get classe suggest handlers.
         * @return the handler.
         */
        HasValue<IdLabelModel> getClassValue();

    }

}
